Zum Hauptinhalt springen

Chapter 5

Designing for Change

"Software does not become difficult because requirements are complex. It becomes difficult because requirements refuse to stand still."


Why This Chapter Exists

Every software project begins with certainty.

The first implementation usually solves today's problem remarkably well.

Only one weapon exists.

Only one runtime object exists.

Only one validation rule exists.

Only one networking model exists.

At this stage, architecture appears obvious.

Additional abstraction feels unnecessary.

The temptation to optimize for today's requirements is enormous.

Unfortunately, software rarely remains in this state for long.

Projects evolve.

Gameplay evolves.

Teams evolve.

The architecture must survive all three.


The Nature of Change

Very few architectural problems appear during the first implementation.

They emerge during the second.

Or the fifth.

Or the twentieth.

A new attachment type is introduced.

Vehicles are added.

Gameplay rules change.

Networking requirements become more demanding.

Content grows exponentially.

Interestingly, these changes rarely invalidate the original feature.

They invalidate the assumptions the feature was built upon.

The true challenge of software engineering is therefore not implementing functionality.

It is managing changing assumptions.


Stable Knowledge and Changing Knowledge

One useful way to think about architecture is to separate knowledge into two categories.

Stable knowledge.

Changing knowledge.

Stable knowledge rarely changes.

For example:

  • Runtime objects exist.
  • Definitions describe authored content.
  • Systems have responsibilities.
  • Multiplayer requires authority.

These ideas remain useful regardless of gameplay.

Changing knowledge evolves constantly.

Damage formulas.

Weapon balancing.

Inventory rules.

Movement mechanics.

Attachment restrictions.

These systems should remain free to evolve without forcing architectural redesign.

The Cube Framework intentionally protects stable knowledge from changing knowledge.

This separation allows gameplay to evolve while infrastructure remains remarkably stable.


Designing for Unknown Requirements

Framework development differs fundamentally from application development.

Applications often solve today's requirements, while frameworks are designed to survive tomorrow's.

This distinction changes how architectural decisions are made.

Rather than asking:

"Does this solve today's problem?"

Framework architects ask:

"Will this decision still make sense when tomorrow's problem arrives?"

The answer is rarely certain.

The goal is therefore not prediction.

The goal is resilience.


Preserving Freedom

Every architectural decision either creates freedom...

...or removes it.

Introducing unnecessary coupling reduces future options.

Combining unrelated responsibilities limits extension.

Hardcoding assumptions makes future change increasingly expensive.

Good architecture deliberately preserves freedom.

Not because future requirements are known.

But because future requirements are inevitable.


Evolution Without Reinvention

Healthy architectures evolve continuously.

They do not require reinvention whenever new functionality appears.

Instead, they absorb change through existing extension points.

Responsibilities remain recognizable.

Terminology remains consistent.

Subsystems continue cooperating exactly as before.

Only the implementation expands.

When architecture survives change without losing its identity, it has achieved one of its primary goals.


Design Note

One of the easiest ways to recognize a healthy architecture is by observing how it reacts to new requirements.

If adding a feature primarily means extending existing concepts, the architecture is likely healthy.

If adding a feature requires redefining existing responsibilities, the architecture deserves another look.


Framework Law V

Architecture should absorb change, not resist it.

Frameworks succeed when new requirements feel like extensions rather than interruptions.


Revision History

Version 1.0

Initial publication.